#ifndef _INCLUDE__DDE_KIT__RESOURCES_H_
#define _INCLUDE__DDE_KIT__RESOURCES_H_

#include <dde_kit/types.h>

static __inline dde_kit_uint8_t dk_inb(int port) __attribute__((always_inline));
static __inline void dk_insb(int port, void *addr, int cnt) __attribute__((always_inline));
static __inline dde_kit_uint16_t dk_inw(int port) __attribute__((always_inline));
static __inline void dk_insw(int port, void *addr, int cnt) __attribute__((always_inline));
static __inline dde_kit_uint32_t dk_inl(int port) __attribute__((always_inline));
static __inline void dk_insl(int port, void *addr, int cnt) __attribute__((always_inline));
static __inline void dk_outb(int port, dde_kit_uint8_t data) __attribute__((always_inline));
static __inline void dk_outsb(int port, const void *addr, int cnt) __attribute__((always_inline));
static __inline void dk_outw(int port, dde_kit_uint16_t data) __attribute__((always_inline));
static __inline void dk_outsw(int port, const void *addr, int cnt) __attribute__((always_inline));
static __inline void dk_outsl(int port, const void *addr, int cnt) __attribute__((always_inline));
static __inline void dk_outl(int port, dde_kit_uint32_t data) __attribute__((always_inline));


static __inline dde_kit_uint8_t
dk_inb(int port)
{
     dde_kit_uint8_t data;
     __asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
     return data;
}

static __inline dde_kit_uint16_t
dk_inw(int port)
{
     dde_kit_uint16_t data;
     __asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
     return data;
}

static __inline dde_kit_uint32_t
dk_inl(int port)
{
     dde_kit_uint32_t data;
     __asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
     return data;
}

static __inline void
dk_outb(int port, dde_kit_uint8_t data)
{
     __asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
}

static __inline void
dk_outw(int port, dde_kit_uint16_t data)
{
     __asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
}

static __inline void
dk_outl(int port, dde_kit_uint32_t data)
{
#ifdef DDE_LINUX
	 // printk("outl %08x => %d\n", (unsigned int)data, port);
#endif
     __asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
}


static __inline void
dk_insb(int port, void *addr, int cnt)
{
     __asm __volatile("cld\n\trepne\n\tinsb"			:
		      "=D" (addr), "=c" (cnt)		:
		      "d" (port), "0" (addr), "1" (cnt)	:
		      "memory", "cc");
}

static __inline void
dk_insw(int port, void *addr, int cnt)
{
     __asm __volatile("cld\n\trepne\n\tinsw"			:
		      "=D" (addr), "=c" (cnt)		:
		      "d" (port), "0" (addr), "1" (cnt)	:
		      "memory", "cc");
}

static __inline void
dk_insl(int port, void *addr, int cnt)
{
     __asm __volatile("cld\n\trepne\n\tinsl"			:
		      "=D" (addr), "=c" (cnt)		:
		      "d" (port), "0" (addr), "1" (cnt)	:
		      "memory", "cc");
}

static __inline void
dk_outsb(int port, const void *addr, int cnt)
{
     __asm __volatile("cld\n\trepne\n\toutsb"		:
		      "=S" (addr), "=c" (cnt)		:
		      "d" (port), "0" (addr), "1" (cnt)	:
		      "cc");
}

static __inline void
dk_outsw(int port, const void *addr, int cnt)
{
     __asm __volatile("cld\n\trepne\n\toutsw"		:
		      "=S" (addr), "=c" (cnt)		:
		      "d" (port), "0" (addr), "1" (cnt)	:
		      "cc");
}

static __inline void
dk_outsl(int port, const void *addr, int cnt)
{
     __asm __volatile("cld\n\trepne\n\toutsl"		:
		      "=S" (addr), "=c" (cnt)		:
		      "d" (port), "0" (addr), "1" (cnt)	:
		      "cc");
}


#define dde_kit_request_io(start, size) 0
#define dde_kit_release_io(start, size) 0
#define dde_kit_inb(port) dk_inb(port)
#define dde_kit_inw(port) dk_inw(port)
#define dde_kit_inl(port) dk_inl(port)
#define dde_kit_outb(port, val) dk_outb(port, val)
#define dde_kit_outw(port, val) dk_outw(port, val)
#define dde_kit_outl(port, val) dk_outl(port, val)
#define dde_kit_insb(port, val, count)  dk_insb(port, val, count)
#define dde_kit_insw(port, val, count)  dk_insw(port, val, count)
#define dde_kit_insl(port, val, count)  dk_insl(port, val, count)
#define dde_kit_outsb(port, val, count) dk_outsb(port, val, count)
#define dde_kit_outsw(port, val, count) dk_outsw(port, val, count)
#define dde_kit_outsl(port, val, count) dk_outsl(port, val, count)

/**
 * Allocate MMIO range
 *
 * \param  start  begin of MMIO range
 * \param  size   size of MMIO range
 * \param  wc     if !0 request write-combined memory mapping
 *
 * \retval vaddr  virtual start address mapped range
 * \return 0 on success, -1 otherwise
 */
int dde_kit_request_mem(dde_kit_addr_t start, dde_kit_size_t size,
                        int wc, dde_kit_addr_t *vaddr);

/**
 * Free MMIO range
 *
 * \param  start  begin of MMIO range
 * \param  size   size of MMIO range
 *
 * \return 0 on success, -1 otherwise
 */
int dde_kit_release_mem(dde_kit_addr_t start, dde_kit_size_t size);

#endif /* _INCLUDE__DDE_KIT__RESOURCES_H_ */
